﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Input;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

using ProtoImaginer.ProtoControl;
using ProtoImaginer.Models;

namespace ProtoImaginer.ProtoPage
{
    public partial class PageView : PhoneApplicationPage
    {
        //pinch related global variable
        private double initialScale;

        private ApplicationBarIconButton addControlButton;
        private ApplicationBarIconButton editTitleButton;
        private ApplicationBarIconButton delControlButton;
        private ApplicationBarIconButton linkPageButton;

        private List<ControlAtom> controls;
        private ControlAtom highlighted;

        public PageView()
        {
            //this should deply all the background UI.
            InitializeComponent();
            controls = new List<ControlAtom>();

            addControlButton = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
            editTitleButton = (ApplicationBarIconButton)ApplicationBar.Buttons[1];
            delControlButton = (ApplicationBarIconButton)ApplicationBar.Buttons[2];
            linkPageButton = (ApplicationBarIconButton)ApplicationBar.Buttons[3];

            AddControl();
            initialScale = 1;

        }

        #region UI handler
        /*=====================================================================
         * Application bar
         *===================================================================*/

        private void AddControlButtonClick(object sender, EventArgs e)
        {
            AddControl();
        }
        private void EditTitleButtonClick(object sender, EventArgs e)
        {
            MessageBox.Show("edit title button clicked.");
        }
        private void DelControlButtonClick(object sender, EventArgs e)
        {
            //TBC
            DelControl();
        }



        private void LinkPageButtonClick(object sender, EventArgs e)
        {
            //TBC
        }
        /*=====================================================================
         * Gestures on Canvas, pinch session.
         *===================================================================*/

        private void CanvasPinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            initialScale = ((CompositeTransform)Canvas.RenderTransform).ScaleX;
        }

        private void CanvasPinchDelta(object sender, PinchGestureEventArgs e)
        {
            var finger1 = e.GetPosition(Canvas, 0);
            var finger2 = e.GetPosition(Canvas, 1);

            Canvas.RenderTransformOrigin = new Point(
                (finger2.X + finger1.X) / 2 / Canvas.ActualWidth,
                (finger2.Y + finger1.Y) / 2 / Canvas.ActualHeight);

            var transform = (CompositeTransform)Canvas.RenderTransform;
            transform.ScaleX = initialScale * e.DistanceRatio;
            transform.ScaleY = transform.ScaleX;
        }

        private void CanvasPinchCompleted(object sender, PinchGestureEventArgs e)
        {
        }


        /*=====================================================================
         * Gestures on Canvas, drag session.
         *===================================================================*/

        //disable pivot's drag event.
        private void CanvasDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
            }
        }

        //drag canvas around.
        private void CanvasDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                Canvas.Margin = new Thickness(
                        Canvas.Margin.Left + e.HorizontalChange,
                        Canvas.Margin.Top + e.VerticalChange,
                        Canvas.Margin.Right - e.HorizontalChange,
                        Canvas.Margin.Bottom - e.VerticalChange);
            }
        }

        //enable pivot's drag event.
        private void CanvasDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
            }
        }

        /*=====================================================================
         * Gestures on Canvas, tap session.
         *===================================================================*/

        //di-highlight current control item, if applicable
        private void CanvasTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            Updatehighlighted(null);
        }
        //reset canvas scale and position.
        private void GraphicViewDoubleTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            CanvasTransformation.ScaleX = 1;
            CanvasTransformation.ScaleY = 1;

            Canvas.Margin = new Thickness(0, 0, 0, 0);
        }

        /*=====================================================================
         * Gestures on Control items, tap session.
         *===================================================================*/

        //show outline and four active dot.
        private void ControlAtomTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                //show outline of active control item.
                ((ControlAtom)sender).Outline(true);

                //enable delete and linkTo button when control item highlighted
                Updatehighlighted((ControlAtom)sender);
            }
        }
        /*=====================================================================
         * Gestures on Control items, drag session.
         *===================================================================*/

        //disable parents' drag gestures
        private void ControlDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                //de-highlight other control items.
                if(highlighted != sender)
                    Updatehighlighted(null);
            }
        }

        //drag control item around.
        private void ControlDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                Canvas.SetLeft((UIElement)sender, Canvas.GetLeft((UIElement)sender) + e.HorizontalChange);
                Canvas.SetTop((UIElement)sender, Canvas.GetTop((UIElement)sender) + e.VerticalChange);
            }
        }

        //enable pivot's drag event & make sure control item is within image.
        private void ControlDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                CheckRangeWithinCanvas((UIElement)sender);
            }
        }
        #endregion

        #region UI control
        /*=====================================================================
         * UI misc.
         *===================================================================*/

        public void CheckRangeWithinCanvas(UIElement controlItem)
        {
            if (Canvas.GetLeft(controlItem) < 0)
                Canvas.SetLeft(controlItem, 0);
            else if (Canvas.GetLeft(controlItem) + ((ControlAtom)controlItem).Width > ControlContainer.Width)
                Canvas.SetLeft(controlItem, ControlContainer.Width - ((ControlAtom)controlItem).Width);

            if (Canvas.GetTop(controlItem) < 0)
                Canvas.SetTop(controlItem, 0);
            else if (Canvas.GetTop(controlItem) + ((ControlAtom)controlItem).Height > ControlContainer.Height)
                Canvas.SetTop(controlItem, ControlContainer.Height - ((ControlAtom)controlItem).Height);
        }
        public void ButtonTrigger()
        {
            if (highlighted == null)
            {
                delControlButton.IsEnabled = false;
                linkPageButton.IsEnabled = false;
            }
            else
            {
                delControlButton.IsEnabled = true;
                linkPageButton.IsEnabled = true;
            }
        }
        /*=====================================================================
         * Edit Control.
         *===================================================================*/

        //add control
        private void AddControl()
        {
            //initialize new control item.
            ControlAtom newItem = new ControlAtom(this);

            //UI layer stuff
            //TODO always throw exception here, don know why.
            try
            {
                ControlContainer.Children.Add(newItem);
                //database related
                controls.Add(newItem);
                //bind listeners
                BindControlItemListener(newItem);

                Canvas.SetLeft(newItem, 100);
                Canvas.SetTop(newItem, 200);
            }
            catch (Exception e) {
                MessageBox.Show("Error: " + e.Message);
            }

        }

        private void DelControl()
        {
            if (highlighted != null)
            {
                ControlContainer.Children.Remove(highlighted);
                controls.Remove(highlighted);

                MessageBox.Show(controls.Count + " controls left in current page");
                //database related remove
                //TODO 

                Updatehighlighted(null);
                ButtonTrigger();
            }
        }

        private void Updatehighlighted(ControlAtom newhighlighted)
        {
            highlighted = newhighlighted;

            foreach (ControlAtom control in controls)
                control.Outline(false);

            if (highlighted != null)
                highlighted.Outline(true);

            ButtonTrigger();
        }
        private void BindControlItemListener(ControlAtom newItem)
        {
            GestureListener listener = GestureService.GetGestureListener(newItem);
            listener.Tap += ControlAtomTap;
            listener.DragStarted += ControlDragStarted;
            listener.DragDelta += ControlDragDelta;
            listener.DragCompleted += ControlDragCompleted;
        }

        #endregion

        #region DatabaseQueryFunction

        
        //public static void CreateDatabase()
        //{

        //    using (ProtoDataContext database = new ProtoDataContext(GlobalVariables.strConnectionString))
        //    {
        //        if (database.DatabaseExists() == false)
        //        {
        //            database.CreateDatabase();
        //            MessageBox.Show("Database Created Successfully!!!");
        //        }
        //        //else { MessageBox.Show("Database already exists!!!"); }
        //    }
        //}

        //public static void AddNewRecord(Project p)
        //{
        //    if (p.ProjectName.Length == 0)
        //    {
        //        MessageBox.Show("null!");
        //        return;
        //    }
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        Project newProject = new Project(
        //            p.ProjectId,
        //            p.ProjectAuthor,
        //            p.ProjectName,
        //            p.ProjectStatus,
        //            p.ProjectDescription,
        //            p.ProjectTag,
        //            p.ProjectCreateDate,
        //            p.ProjectLastModifiedDate
        //            );
        //        database.Projects.InsertOnSubmit(newProject);
        //        try
        //        {
        //            database.SubmitChanges();
        //        }
        //        catch (Exception e1)
        //        {
        //            Console.WriteLine(e1);
        //            database.SubmitChanges();
        //        }
        //        MessageBox.Show("Employee Added Successfully!!!");
        //    }
        //}

        //public static IList<Project> FetchAllRecords()
        //{
        //    //IList<Project> RecordList = new List<Project>();
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        IQueryable<Project> query
        //            = from pjt in database.Projects
        //              orderby pjt.ProjectLastModifiedDate descending
        //              //orderby pjt.Field<DateTime>("ProjectLastModifiedDate")
        //              select pjt;
        //        return query.ToList();
        //    }
        //}

        //public static Project QueryProjectRecordById(string id)
        //{

        //    IList<Project> RecordList = null;
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        IQueryable<Project> query = from pjt in database.Projects where pjt.ProjectId == id.ToString() select pjt;
        //        RecordList = query.ToList();
        //    }
        //    return RecordList[0];
        //}

        //public static void ListAllProjectRecords()
        //{
        //    IList<Project> PjtList = null;
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        IQueryable<Project> query = from pjt in database.Projects select pjt;
        //        PjtList = query.ToList();
        //    }
        //    StringBuilder strBuilder = new StringBuilder();
        //    strBuilder.AppendLine("Project List");
        //    foreach (Project pt in PjtList)
        //    {
        //        strBuilder.AppendLine("Name - " + pt.ProjectName + " Created On - " + pt.ProjectCreateDate.ToString());
        //    }
        //    MessageBox.Show(strBuilder.ToString());
        //}

        ////NOT WORK
        //public static void UpdateRecords(Project p)
        //{
        //    if (p.ProjectName.Length == 0)
        //    {
        //        MessageBox.Show("null!");
        //        return;
        //    }
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        IQueryable<Project> record = from pjt in database.Projects where pjt.ProjectId == p.ProjectId select pjt;
        //        Project projectToUpdate = record.FirstOrDefault();
        //        projectToUpdate.ProjectLastModifiedDate = DateTime.Now;
        //        projectToUpdate.ProjectDescription = p.ProjectDescription;
        //        projectToUpdate.ProjectName = p.ProjectName;
        //        projectToUpdate.ProjectTag = p.ProjectTag;
        //        database.SubmitChanges();
        //        MessageBox.Show("Employee Modified Successfully!!!");
        //    }
        //}

        //public static void DeleteRecord(Project p)
        //{
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        IQueryable<Project> query = from pjt in database.Projects where pjt.ProjectId == p.ProjectId select pjt;
        //        Project PjtToRemove = query.FirstOrDefault();
        //        database.Projects.DeleteOnSubmit(PjtToRemove);
        //        database.SubmitChanges();
        //        MessageBox.Show("Project Deleted Successfully!!!");
        //    }
        //}

        //public static void DeleteDatabase()
        //{
        //    using (ProtoDataContext database = new ProtoDataContext(strConnectionString))
        //    {
        //        if (database.DatabaseExists())
        //        {
        //            database.DeleteDatabase();
        //            MessageBox.Show("Database Deleted Successfully!!!");
        //        }
        //    }
        //}
        #endregion
    }
}